LSP Project

Author: Yangcheng Gu, Zhen Tong

Implement the Live Sequence Protocol (LSP) is a homegrown protocol for providing reliable communication with simple client and server APIs on top of the Internet UDP protocol. In this project of Go language, we implement

The project will be divided into 2 checkpoints:

Part I Basic

First, we will implement the very basic Server, Client that can be connected, read, and write, with a naive lsp buffer. When the connect establish, each client has one lsp buffer, and each server add one new lsp buffer. The lsp buffer contain the state of sending and receive between the Client and Server.

Now, let’s talk about the Write(), and Read(). The Client and Server are similar in the Read and Write() behavior. Therefore, we used the Instance as a super class for them. Whenever the instance receive data from UDP read, it will receive it using the receiveMessages, check the correctness of the message. Then, it will pass the udpMessage struct to the processMessages . The processMessages is used to detect what kind of request it is, and pass the Request with type and send to the manageRequest . The manageRequest is will call specific function to handle the task.

Now, we will talk about the detail of saveInboundMessage() and relayOutboundMessage() . These two functions are actually calling the lsp buffer’s method of the same function name.

When the saveInboundMessage(msg *Message) is called, it will immediately response the message with Ack. When the instance is not asked to close, the lsp buffer will add the message into the recvMsgBuffer, and then check all the message in the recvMsgBuffer , and read them out into inboxChan. Then the read() function can return the message from the inboxChan .(We will talk about the readQueueand inMsgQueuelater when we encounter the slow Read problem)

When the relayOutboundMessage(msg *Message) function is called, the lsp buffer will add the message to the outMsgQueue , then call the updateOutbox() to check if the message can be send. The updateOutbox() will check if the the message to be sent is not exceeding the Max unacknowledged message. Until the outMsgQueue is not empty and the the Sequence Number of message to be send is not reaching the window maximum, the updateOutbox() will send the message to the outboxChan.

Ack & CAck

After the instance received an Ack, the manageRequest will call the ackMessage that delete the message of that sequence number in the lspBuffer.sentMsgBuffer . After that, the lsbBuffer will update the new nextUnackedSeqNum and call updateOutbox() , so that some more message can ready to send.

CAck is similar to Ack, the manageRequest will call the cAckMessage() . This function will delete all the message of the sequence number from nextUnackedSeqNum to cAck.seqNum

Part II Robustness

When the network between the server and client is not stable, the message of data-sending and acknowledge.

Epoch

Epoch is a strategy in LSP, a timer to send message to let the other side know that the connection is still on. It basically do three things:

Part III Close Instance

When the instance want to appropriately close the resource, it needs to conduct two steps.

When we start the instance, the instance will start a go routing called closeManager . It will first trigger the first step “Close all the connections”. The lsb buffer will change the pendingClose to true . Under that condition, the instance will:

After that, the instance will try to check if there no more unacked message, and no more message to be sent (Write() request before Close()). If not, wait some epoch, and the message will be acked, and will be sent. If the condition is satisfied, close the connection.

The second step of the close, end all the go routine is rather simple. Close the chan they are using will give go routine a signal that it need to be end.